home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / awe2-0_1.lha / awe2-0.1 / Src / RCS / GenericHeap.cc,v < prev    next >
Text File  |  1989-02-20  |  7KB  |  363 lines

  1. head     3.2;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @@;
  7.  
  8.  
  9. 3.2
  10. date     89.02.20.15.34.45;  author grunwald;  state Exp;
  11. branches ;
  12. next     3.1;
  13.  
  14. 3.1
  15. date     88.12.20.13.48.47;  author grunwald;  state Exp;
  16. branches ;
  17. next     1.2;
  18.  
  19. 1.2
  20. date     88.10.30.13.03.07;  author grunwald;  state Exp;
  21. branches ;
  22. next     1.1;
  23.  
  24. 1.1
  25. date     88.09.18.16.42.22;  author grunwald;  state Exp;
  26. branches ;
  27. next     ;
  28.  
  29.  
  30. desc
  31. @@
  32.  
  33.  
  34. 3.2
  35. log
  36. @Start using Gnu library heaps for schedulers
  37. @
  38. text
  39. @// This may look like C code, but it is really -*- C++ -*-
  40. // 
  41. // Copyright (C) 1988 University of Illinois, Urbana, Illinois
  42. //
  43. // written by Dirk Grunwald (grunwald@@cs.uiuc.edu)
  44. //
  45. #include "Awesime.h"
  46. #include "stream.h"
  47. //
  48. //    This defines a Pairing Heap structure for a pointer data type.
  49. //
  50. //    See ``The Pairing Heap: A New Form of Self-Adjusting Heap''
  51. //    Fredman, Segdewick et al,
  52. //    Algorithmica (1986) 1:111-129
  53. //
  54. //    In particular, this implements the pairing heap using the circular
  55. //    list.
  56. //
  57. //
  58.  
  59. #ifndef HEAP_INDEX
  60. #define HEAP_INDEX unsigned short
  61. #endif
  62.  
  63. #ifndef HEAP_INDEX_NULL
  64. #define HEAP_INDEX_NULL 0xffff
  65. #endif
  66.  
  67. #define NIL    GENERIC2(HEAP_NAME,Null)
  68. #define INDEX    GENERIC2(HEAP_NAME,Index)
  69. #define ITEM    GENERIC2(HEAP_NAME,Item)
  70. #define RECORD    GENERIC2(HEAP_NAME,Record)
  71.  
  72. const INDEX NIL = HEAP_INDEX_NULL;
  73. static const char *GENERIC2(HEAP_NAME,Name) = GENERIC_STRING(HEAP_NAME) ;
  74.  
  75. HEAP_NAME::HEAP_NAME(int length, bool xdebug)
  76.     : (xdebug)
  77. {
  78.     freelist = NIL;
  79.     allocatedSize = 0;
  80.     root = NIL;
  81.     elements = 0;
  82.     makeRoom(length);
  83. }
  84.  
  85. INDEX HEAP_NAME::getCell()
  86. {
  87.     if (freelist == NIL) {
  88.     makeRoom(0);
  89.     }
  90.     INDEX cell = freelist;
  91.     pValid[freelist] = 1;
  92.     freelist = storage[freelist].sibling;
  93.     elements++;
  94.     return(cell);
  95. }
  96.  
  97. void
  98. HEAP_NAME::returnCell(INDEX cell)
  99.     storage[cell].sibling = freelist;
  100.     pValid[cell] = 0;
  101.     freelist = cell;
  102.     elements--;
  103. }
  104.  
  105. void
  106. HEAP_NAME::makeRoom(int atLeast)
  107. {
  108.     //
  109.     //    Out of free space?
  110.     //
  111.     if (freelist == NIL) {
  112.     //
  113.     // Is there existing storage?
  114.     //
  115.     if (allocatedSize > 0) {
  116.         //
  117.         // Get new storage, copy over existing data & delete old storage
  118.         // 
  119.         INDEX newSize = (allocatedSize * 3) / 2;
  120.  
  121.         RECORD *newStorage = new RECORD[newSize];
  122.         char *newValid = new char[newSize];
  123.         if (newStorage == 0 || newValid == 0) {
  124.         cerr << "[" << GENERIC2(HEAP_NAME,Name) << "::makeRoom] Out of storage space\n";
  125.         exit(1);
  126.         }
  127.         bcopy(storage, newStorage, allocatedSize * sizeof(RECORD));
  128.         bcopy(pValid, newValid, allocatedSize * sizeof(char));
  129.         delete storage;
  130.         delete pValid;
  131.         storage = newStorage;
  132.         pValid = newValid;
  133.         //
  134.         // Chain the new stuff into the free list
  135.         //
  136.         for (int i = allocatedSize; i < newSize; i++) {
  137.         storage[i].sibling = i+1;
  138.         pValid[i] = 0;
  139.         }
  140.         storage[newSize-1].sibling = NIL;
  141.         freelist = allocatedSize;
  142.         allocatedSize = newSize;
  143.     } else {
  144.         //
  145.         // No existing space
  146.         //
  147.         if (atLeast <= 8) {
  148.         allocatedSize = 8;
  149.         } else {
  150.         allocatedSize = atLeast;
  151.         }
  152.         storage = new RECORD[allocatedSize];
  153.         pValid = new char[allocatedSize];
  154.         if (storage == 0) {
  155.         cerr << "[" << GENERIC2(HEAP_NAME,Name) << "::getCell] Out of storage\n";
  156.         exit(1);
  157.         }
  158.         for (int i = 0; i < allocatedSize; i++) {
  159.         storage[i].sibling = i+1;
  160.         pValid[i] = 0;
  161.         }
  162.         storage[allocatedSize-1].sibling = NIL;
  163.         freelist = 0;
  164.     }
  165.     }
  166. }
  167.  
  168. //
  169. // makeChild takes two nodes and makes one the child of the other
  170. // and returns the index of the new parent. 
  171. //
  172. // We play fast and loose with the siblings field of a & b, although
  173. // we maintain the siblings of the children.
  174. //
  175. INDEX
  176. HEAP_NAME::makeChild(INDEX a, INDEX b)
  177. {
  178.     INDEX parent;
  179.     INDEX child;
  180.     
  181.     if (storage[a].item <= storage[b].item) {
  182.     parent = a; child = b;
  183.     } else {
  184.     parent = b; child = a;
  185.     }
  186.     //
  187.     // If the new parent has no children, simply add the new child.
  188.     // We assume that the child and the parent dont care about
  189.     // their *sibling* nodes
  190.     //
  191.     INDEX popsKid = storage[parent].children;
  192.     
  193.     if (popsKid == NIL) {
  194.     storage[parent].children = child;
  195.     storage[child].sibling = child;
  196.     } else {
  197.     INDEX temp = storage[popsKid].sibling;
  198.     storage[popsKid].sibling = child;
  199.     storage[child].sibling = temp;
  200.     storage[parent].children = child;
  201.     }
  202.     return(parent);
  203. }
  204.  
  205. void
  206. HEAP_NAME::add(ITEM &item)
  207. {
  208.     INDEX cell = getCell();
  209.  
  210.     storage[cell].item = item;
  211.     storage[cell].children = NIL;
  212.     storage[cell].sibling = NIL;
  213.     
  214.     if (root == NIL) {
  215.     root = cell;
  216.     } else {
  217.      //
  218.     //    Make cell a child of root. Root may have no kids.
  219.     //
  220.     root = makeChild(root,cell);
  221.     }
  222. }
  223.  
  224. //
  225. //    Item remove is the most complicated routine.
  226. //
  227. //    We remove the root (should there be one) and then select a new
  228. //    root. The siblings of the root are in a cicular list. We continue
  229. //    to pair elements in this list until there is a single element.
  230. //    This element will be the new root.
  231. bool
  232. HEAP_NAME::remove(ITEM &removed)
  233. {
  234.     bool valid = FALSE;
  235.     
  236.     do {
  237.     if (root == NIL || elements <= 0) {
  238.         return(0);
  239.     }
  240.     
  241.     removed = storage[root].item;
  242.     valid = pValid[root];
  243.     
  244.     INDEX child = storage[root].children;
  245.     returnCell(root);
  246.     
  247.     if (child == NIL) {
  248.         root = NIL;
  249.     } else {
  250.         while(storage[child].sibling != child) {
  251.         //
  252.         // We have at least two kids, but we may only have
  253.         // two kids. So, oneChild != child, but it is possible
  254.         // that twoChild == child.
  255.         //
  256.         INDEX oneChild = storage[child].sibling;
  257.         INDEX twoChild = storage[oneChild].sibling;
  258.         //
  259.         // Remove the two from the sibling list
  260.         //
  261.         storage[child].sibling = storage[twoChild].sibling;
  262.         storage[oneChild].sibling = NIL;
  263.         storage[twoChild].sibling = NIL;
  264.         
  265.         INDEX bestChild = makeChild(oneChild, twoChild);
  266.         
  267.         if (twoChild == child) {
  268.             //
  269.             // We have reduced the two to one, so we'll be exiting.
  270.             //
  271.             child = bestChild;
  272.             storage[child].sibling = child;
  273.         } else {
  274.             //
  275.             // We've removed two siblings, now we need to insert
  276.             // the better of the two
  277.             //
  278.             storage[bestChild].sibling = storage[child].sibling;
  279.             storage[child].sibling = bestChild;
  280.             child = storage[bestChild].sibling;
  281.         }
  282.         }
  283.         root = child;
  284.     }
  285.     } while ( !valid );
  286.     return(1);
  287. }
  288.  
  289. bool
  290. HEAP_NAME::doStart(INDEX &index)
  291. {
  292.     for (index = 0; index < allocatedSize; index++) {
  293.     if (pValid[index]) {
  294.         return(TRUE);
  295.     }
  296.     }
  297.     return(FALSE);
  298. }
  299.  
  300. bool
  301. HEAP_NAME::doDelete(INDEX &index)
  302. {
  303.     if (pValid[index]) {
  304.     pValid[index] = FALSE;
  305.     elements--;
  306.     return(TRUE);
  307.     } else {
  308.     return( FALSE );
  309.     }
  310. }
  311.  
  312. bool
  313. HEAP_NAME::doNext(INDEX& index)
  314. {
  315.     //
  316.     // If they are moving on to the next element,
  317.     // they are sitting on the current on. So, move to the next
  318.     // and then look for a valid one.
  319.     //
  320.     for (index++; index < allocatedSize; index++) {
  321.     if (pValid[index]) {
  322.         return(TRUE);
  323.     }
  324.     }
  325.     return(FALSE);
  326. }
  327.  
  328. void
  329. HEAP_NAME::doDone()
  330. {
  331.     //
  332.     // Do nothing.
  333.     //
  334. }
  335.  
  336. @
  337.  
  338.  
  339. 3.1
  340. log
  341. @Steay version
  342. @
  343. text
  344. @@
  345.  
  346.  
  347. 1.2
  348. log
  349. @*** empty log message ***
  350. @
  351. text
  352. @@
  353.  
  354.  
  355. 1.1
  356. log
  357. @Initial revision
  358. @
  359. text
  360. @d1 6
  361. @
  362.